package com.eclipse.training.listeners;

import java.util.ArrayList;
import java.util.Iterator;

import org.eclipse.jface.viewers.StructuredSelection;
import org.eclipse.jface.viewers.Viewer;
import org.eclipse.jface.viewers.ViewerDropAdapter;
import org.eclipse.swt.dnd.DND;
import org.eclipse.swt.dnd.TransferData;

import com.eclipse.training.model.AbstractUniverseElement;

public class TableDropAdapter extends ViewerDropAdapter {

	private int location;
	private Object target;

	public TableDropAdapter(Viewer viewer) {
		super(viewer);
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see
	 * org.eclipse.jface.viewers.ViewerDropAdapter#performDrop(java.lang.Object)
	 */
	@SuppressWarnings({ "rawtypes", "unchecked" })
	@Override
	public boolean performDrop(Object data) {
		boolean done = false;
		Viewer viewer = getViewer();

		if (data instanceof AbstractUniverseElement[]) {

			StructuredSelection selection = (StructuredSelection) viewer
					.getSelection();

			ArrayList<AbstractUniverseElement> content = ((ArrayList<AbstractUniverseElement>) viewer
					.getInput());
			ArrayList<AbstractUniverseElement> moved = new ArrayList<AbstractUniverseElement>();

			int index = content.indexOf(target);

			if (content.size() != 1) {
				Iterator it = selection.iterator();
				while (it.hasNext()) {
					AbstractUniverseElement item = (AbstractUniverseElement) it
							.next();
					moved.add(item);
					content.remove(item);
				}

				switch (location) {
				case ViewerDropAdapter.LOCATION_AFTER:
					if (content.size() > 1) {
						content.addAll((index < content.size() ? index + 1
								: content.size() - 1), moved);
						viewer.refresh();
					}
					done = true;
					break;
				case ViewerDropAdapter.LOCATION_BEFORE:
					content.addAll(index, moved);
					viewer.refresh();
					done = true;
					break;
				case ViewerDropAdapter.LOCATION_ON:
					done = false;
					break;
				case ViewerDropAdapter.LOCATION_NONE:
				default:
					done = false;
					break;

				}
			}
		}

		return done;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see
	 * org.eclipse.jface.viewers.ViewerDropAdapter#validateDrop(java.lang.Object
	 * , int, org.eclipse.swt.dnd.TransferData)
	 */
	@Override
	public boolean validateDrop(Object target, int operation,
			TransferData transferType) {
		boolean done = false;
		this.target = null;

		if (target instanceof AbstractUniverseElement
				&& operation == DND.DROP_MOVE) {
			this.location = getCurrentLocation();
			this.target = target;

			switch (this.location) {
			case ViewerDropAdapter.LOCATION_AFTER:
				done = true;
				break;
			case ViewerDropAdapter.LOCATION_BEFORE:
				done = true;
				break;
			case ViewerDropAdapter.LOCATION_ON:
				done = false;
				break;
			case ViewerDropAdapter.LOCATION_NONE:
			default:
				done = false;
				break;
			}
		}
		return done;
	}

}
